#ifndef _UTIL_HPP
#define _UTIL_HPP
/* 
重启
buff[off] = '\0';
esp_system_abort(buff);

*/

uint64_t startTime, endTime;


uint64_t getTimeMs() {
	struct timeval tv_now;
	gettimeofday(&tv_now, NULL);
	return (int64_t)tv_now.tv_sec * 1000L + (int64_t)tv_now.tv_usec;
}

uint64_t getTimeUs() {
	struct timeval tv_now;
	gettimeofday(&tv_now, NULL);
	return (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
}

void sysTimeDiff(bool s, char *str) {
	if(!s) {
		endTime = 0;
		log("TEST: %s\n", str);
		startTime = getTimeUs();
	}
	else if(s) {
		endTime = getTimeUs();
		log("\033[40;33mstart = %lld, end = %lld, diff = %lld\033[0m\n", startTime, endTime, endTime - startTime);
	}
}
void sysShowHeapOnce() {
	log("\n\n=== heap:%u ===\n", esp_get_free_heap_size());
}
void sysShowHeap() {
	while(1) {
		sysShowHeapOnce();
		DELAY(1000);
	}
}


void sysGetTaskState(char *name) {
	eTaskState state = eTaskGetState(xTaskGetHandle(name));
	if(state == eRunning) {
		log("eRunning\n");
	}
	else if(state == eReady) {
		log("eReady\n");
	}
	else if(state == eBlocked) {
		log("eBlocked\n");
	}
	else if(state == eSuspended) {
		log("eSuspended\n");
	}
	else if(state == eDeleted) {
		log("eDeleted\n");
	}
	else if(state == eInvalid) {
		log("eInvalid\n");
	}
}

// char *sysGetErr(esp_err_t err) {
// 	switch(err) {
// 		case ESP_OK:
// 		return "ESP_OK";
// 		break;

// 		case ESP_FAIL:
// 		return "ESP_FAIL";
// 		break;

// 		case ESP_ERR_NO_MEM:
// 		return "ESP_ERR_NO_MEM";
// 		break;

// 		case ESP_ERR_INVALID_ARG:
// 		return "ESP_ERR_INVALID_ARG";
// 		break;

// 		case ESP_ERR_INVALID_STATE:
// 		return "ESP_ERR_INVALID_STATE";
// 		break;

// 		case ESP_ERR_INVALID_SIZE:
// 		return "ESP_ERR_INVALID_SIZE";
// 		break;

// 		case ESP_ERR_NOT_FOUND:
// 		return "ESP_ERR_NOT_FOUND";
// 		break;

// 		case ESP_ERR_NOT_SUPPORTED:
// 		return "ESP_ERR_NOT_SUPPORTED";
// 		break;

// 		case ESP_ERR_TIMEOUT:
// 		return "ESP_ERR_TIMEOUT";
// 		break;

// 		case ESP_ERR_INVALID_RESPONSE:
// 		return "ESP_ERR_INVALID_RESPONSE";
// 		break;

// 		case ESP_ERR_INVALID_CRC:
// 		return "ESP_ERR_INVALID_CRC";
// 		break;

// 		case ESP_ERR_INVALID_VERSION:
// 		return "ESP_ERR_INVALID_VERSION";
// 		break;

// 		case ESP_ERR_INVALID_MAC:
// 		return "ESP_ERR_INVALID_MAC";
// 		break;

// 		case ESP_ERR_NOT_FINISHED:
// 		return "ESP_ERR_NOT_FINISHED";
// 		break;

// 		case ESP_ERR_WIFI_BASE:
// 		return "ESP_ERR_WIFI_BASE";
// 		break;

// 		case ESP_ERR_MESH_BASE:
// 		return "ESP_ERR_MESH_BASE";
// 		break;

// 		case ESP_ERR_FLASH_BASE:
// 		return "ESP_ERR_FLASH_BASE";
// 		break;

// 		case ESP_ERR_HW_CRYPTO_BASE:
// 		return "ESP_ERR_HW_CRYPTO_BASE";
// 		break;

// 		case ESP_ERR_MEMPROT_BASE:
// 		return "ESP_ERR_MEMPROT_BASE";
// 		break;
// 	}
// }

void sysShowTaskInfo() {
	// USE_TRACE_FACILITY
	// USE_STATS_FORMATTING_FUNCTIONS
	// char *buf;
	// int handlerCont = 3;
	// TaskHandle_t handleList[] = {rotInitH, keyInitH, uiInitH};
	// TaskHandle_t handleList[] = {0};
	char *pbuffer = (char *)calloc(1, 1024);
	while(1) {
		
		// for(int i = 0 ; i < handlerCont; i++)
		// {
		// 	char *taskTag = pcTaskGetName(handleList[i]);
		// 	UBaseType_t cStack = uxTaskGetStackHighWaterMark(handleList[i]);
		// 	log("%s\tStack = %d",taskTag, cStack);
		// }
		
		// vTaskList(&buf);
		// printf("%s\n", buf);

		
		printf("\n==================== heap:%u ====================\n", esp_get_free_heap_size());
		printf("name\t\tstatus\tPriority\tstack\n");
		printf("---------------------------------------------------\n");
		vTaskList(pbuffer);
		printf("%s", pbuffer);
		printf("===================================================\n");
		

		DELAY(1000);
	}
	free(pbuffer);
}

void showStack(TaskHandle_t t) {
	#ifdef CONFIG_MODE
		UBaseType_t cStack;
		char *taskTag = pcTaskGetName(t);
		while(1)
		{
			cStack = uxTaskGetStackHighWaterMark(t);
			log("%s Stack = %d",taskTag, cStack);
			vTaskDelay(pdMS_TO_TICKS(1000));
		}
	#endif
}



#endif